package com.webdrider.servlet.action.user;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.common.model.abstracts.AbstractRequest;
import com.common.model.abstracts.AbstractValidator;
import com.common.model.validators.ActionValidator;
import com.common.security.abstracts.AbstractError;
import com.common.security.abstracts.AbstractException;
import com.common.security.abstracts.AbstractRuntimeException;
import com.common.security.errors.ParserError;
import com.common.security.exceptions.ManagerException;
import com.common.security.exceptions.ParserException;
import com.common.security.exceptions.UserException;
import com.common.servlet.abstracts.AbstractParserServlet;
import com.common.servlet.interfaces.IParser;
import com.webdrider.manager.action.user.UserManager;
import com.webdrider.manager.interfaces.IUserManager;
import com.webdrider.model.action.user.User;
import com.webdrider.model.requests.user.LoginRequest;
import com.webdrider.model.response.user.LoginResponse;
import com.webdrider.model.validators.LoginValidator;
import com.webdrider.security.errors.CredentialsError;
import com.webdrider.security.errors.UserError;
import com.webdrider.servlet.util.RequestAction;
import com.webdrider.servlet.util.parser.user.LoginXMLParser;
import com.webdrider.util.SessionCacheContainer;

/**
 * 
 * 
 * @author Ady
 *
 */
public class LoginServlet extends AbstractParserServlet {
	private static final long serialVersionUID = 1L;
	private static List<AbstractValidator> validators = new ArrayList<AbstractValidator>();
	
	private LoginRequest requestContent;
	private LoginXMLParser parser = new LoginXMLParser();
	private IUserManager manager = new UserManager();
	
	static {
		validators.add(new ActionValidator(RequestAction.LOGIN));
		validators.add(new LoginValidator());
	}
	
	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response) {
		String username = requestContent.getUsername();
		String password = requestContent.getPassword();
		try {
			User user = manager.login(username, password);
			SessionCacheContainer.deleteSession(user.getId());
			String sessionId = SessionCacheContainer.createSession(user.getId(), user.getUserType());
			
			LoginResponse loginResponse = new LoginResponse();
			loginResponse.setRequestAction(requestContent.getAction());
			loginResponse.setSessionId(sessionId);
			
			response.setContentType("text/xml");
			response.getWriter().write(parser().parseResponse(loginResponse));
			response.getWriter().close();
		} catch (ManagerException managerException) {
			exception(managerException, response);
		} catch (UserException userException) {
			exception(userException, response);
		} catch (ParserException parserException) {
			exception(parserException, response);
		} catch (IOException ioException) {
			error(new ParserError(ParserError.STREAM_ERROR), response);
		}
	}

	@Override
	public void setRequest(AbstractRequest abstractRequest) {
		requestContent = (LoginRequest) abstractRequest;
	}
	
	@Override
	public List<AbstractValidator> getValidators() {
		return validators;
	}

	@Override
	public IParser parser() {
		return parser;
	}
	
	@Override
	public void exception(AbstractException exception, HttpServletResponse response) {
		super.exception(exception, response);
		
		switch (exception.getCode()) {
			 case ManagerException.DATABASE_EXCEPTION: {
				 error(new UserError(AbstractError.DATABASE_ERROR), response);
			 }
		}
	}
	
	@Override
	public void exception(AbstractRuntimeException exception, HttpServletResponse response) {
		switch (exception.getCode()) {
			case UserException.USER_NOT_FOUND: {
					error(new CredentialsError(CredentialsError.USER_PASSWORD_NOT_MATCH), response);
					break;
			}
			case UserException.MULTIPLE_USERS_FOUND: {
				error(new UserError(AbstractError.DATABASE_ERROR), response);
				break;
			}
		}
	}
}
